package com.alex.controller.Reference;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch._types.query_dsl.*;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.json.JsonData;
import com.alex.common.beans.ResultBean;
import com.alex.common.config.IndexConfig;
import com.alex.entity.ArticleReferenceEntity;
import com.alex.entity.PageList;
import com.alex.service.AllQueryBasicService;
import com.alex.utils.EsClient;
import com.alex.utils.StringUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import static com.alex.controller.SearchController.checkPage;
import static com.alex.controller.SearchController.printEsBySearchRequest;

/**
 * @Author: 张福垒
 * @Date: 2024/11/13 13:40
 * @Description:
 * @phone: 13864677931
 */
@RestController
@RequestMapping("/reference_search")
@SuppressWarnings(value = "all")
@Slf4j
public class ReferenceSearchController {
    private static ElasticsearchClient client = EsClient.client();

    @GetMapping(value = "search")
    public ResultBean<Object> search(String param, Integer page, Integer limit, Integer isCns, Integer thYear, String jif) {
        BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();

        if (param.startsWith("\"") && param.endsWith("\"")) {
            param = param.substring(0, param.length() - 1);
            param = param.substring(1);
            String finalParam1 = param;
            boolQueryBuilder.must(MatchPhraseQuery.of(i -> i.field("article").query(finalParam1.toLowerCase()).slop(0))._toQuery());
        } else {
            String finalParam = param;
            boolQueryBuilder.must(MatchQuery.of(i -> i.field("article").query(finalParam))._toQuery());
        }

        // boolQueryBuilder.mustNot(MatchQuery.of(i -> i.field("addr").query("Abstract"))._toQuery());
        if (isCns != null) {
            boolQueryBuilder.must(TermQuery.of(i -> i.field("is_cns").value(1))._toQuery());
        }
        if (null != thYear) {
            Query rangeQuery = RangeQuery.of(i -> i.field("year").gte(JsonData.fromJson(2021 + ".0")).lte(JsonData.fromJson(2024 + ".0")))._toQuery();
            boolQueryBuilder.must(rangeQuery);
        }
        if (StringUtil.isNotNull(jif)) {
            String[] split = jif.split("_");
            System.out.println("影响因子左侧:" + split[0]);
            System.out.println("影响因子右侧:" + split[1]);
            Query rangeQuery = RangeQuery.of(i -> i.field("jcr_if").gte(JsonData.fromJson(split[0] + ".0")).lte(JsonData.fromJson(split[1] + ".0")))._toQuery();
            boolQueryBuilder.must(rangeQuery);
        }
        List<Integer> integers = checkPage(page, limit);
        SearchResponse<ArticleReferenceEntity> response = null;

        try {

            SearchRequest.Builder builder = new SearchRequest.Builder();
            builder.index(IndexConfig.REFERENCE_INDEX);
            builder.from(integers.get(0));
            builder.size(integers.get(1));
            builder.highlight(h -> h.preTags("<span style=\"color:red\">").postTags("</span>")
                    .fields("article", highlightFieldBuilder -> highlightFieldBuilder.numberOfFragments(0).fragmentSize(1000))
            );
            builder.query(boolQueryBuilder.build()._toQuery());
            SearchRequest searchRequest = builder.build();
            //打印DSL
            printEsBySearchRequest(searchRequest);
            response = client.search(searchRequest, ArticleReferenceEntity.class);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        List<Hit<ArticleReferenceEntity>> hits = response.hits().hits();
        for (Hit<ArticleReferenceEntity> hit : hits) {
            ArticleReferenceEntity source = hit.source();
            if (source == null) {
                return null;
            }
            Map<String, List<String>> highlight = hit.highlight();
            highlight.forEach((k, v) -> {
                if (k.equals("article")) {
                    source.setArticle(v.get(0));
                }
            });
        }
        List<ArticleReferenceEntity> resultList = AllQueryBasicService.coventList(hits);


        for (ArticleReferenceEntity referenceEntity : resultList) {
            try {
                String cite = referenceEntity.getCite();
                JSONObject jsonObject = JSONObject.parseObject(cite);
                referenceEntity.setCiteJson(jsonObject);
            } catch (Exception e) {
            }
            referenceEntity.setCite(null);
        }
        long value = response.hits().total().value();
        System.out.println("命中数量_" + value);
        PageList<ArticleReferenceEntity> pageList = new PageList<>();
        pageList.setUuid(null);
        pageList.setTotalElements(value);
        pageList.setList(resultList);
        pageList.setTotalPages((int) (value / limit < 1 ? 1 : (value / limit) + 1));//总页数
        pageList.setCurrentPage(page);//当前页
        pageList.setPageSize(limit);//每页显示条数
        return new ResultBean<>(pageList);
    }

}
